package com.nlp.visualization.service.tasks;

import com.google.gson.Gson;
import com.nlp.visualization.core.seg.ISegmentService;
import com.nlp.visualization.core.seg.SegmentFactory;
import com.nlp.visualization.core.seg.SegmentType;
import com.nlp.visualization.core.seg.filter.SegFilter;
import com.nlp.visualization.pojo.NLP.weibo.WeiboCSVEntity;
import com.nlp.visualization.pojo.NLP.weibo.WeiboContentEntity;
import com.nlp.visualization.pojo.NLP.weibo.WeiboSegEntity;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.RecursiveAction;

import static com.nlp.visualization.common.CONSTANTS.TASK_MAX;

public class WeiboSeg2TxtTask extends RecursiveAction {
    Logger logger = LoggerFactory.getLogger(WeiboSeg2TxtTask.class);
    // 每个"小任务"最多只50个数
    private static final int MAX = TASK_MAX;

    private int start;
    private int end;
    private List<WeiboCSVEntity> lines;
    private ConcurrentLinkedQueue<String> queue;
    private SegmentType method;
    private SegFilter filter;

    public WeiboSeg2TxtTask(int start, int end, List lines, ConcurrentLinkedQueue<String> queue, SegmentType method, SegFilter filter) {
        this.start = start;
        this.end = end;
        this.lines = lines;
        this.queue = queue;
        this.method = method;
        this.filter = filter;

    }

    @Override
    protected void compute() {
        // 当end-start的值小于MAX时候，开始执行任务
        if ((end - start) < MAX) {
            for (int i = start; i < end; i++) {
                Gson gson = new Gson();
                //将文件读到的json转换成初始文件的实体
                WeiboCSVEntity csv = lines.get(i);
                //将微博的内容转成微博info的对象
                WeiboContentEntity weiboContent = gson.fromJson(csv.getWeibo_info().replaceAll("\\\\", ""), WeiboContentEntity.class);
                //实例化一个要返回的对象
                WeiboSegEntity seg = new WeiboSegEntity();
                //判断是否是原创微博
                if (!weiboContent.isIs_reprint_weibo()) {
                    //分词过程，往queue里面添加信息
                    queue.add(fillSeg(weiboContent, method, filter));
                } else {
                    //不是原创微博，跳过本条记录
                    continue;
                }
            }
        } else {
            // 将大任务分解成两个小任务
            int middle = (start + end) / 2;
            WeiboSeg2TxtTask left = new WeiboSeg2TxtTask(start, middle, lines, queue, method, filter);
            WeiboSeg2TxtTask right = new WeiboSeg2TxtTask(middle, end, lines, queue, method, filter);
            // 并行执行两个小任务
            left.fork();
            right.fork();
        }
    }

    /**
     * 填充返回的数据
     *
     * @param weiboContent 一条微博内容的实体
     * @param method       采用分词的方式
     */
    private String fillSeg(WeiboContentEntity weiboContent, SegmentType method, SegFilter filter) {

                   ISegmentService segmentService = SegmentFactory.getInstance();
            String content = weiboContent.getWeibo_content().split("\u200B\u200B\u200B")[0];
            content = filterEmoji(content);
            try {
                List<String> segResults = segmentService.executeSeg(content, method, filter);
                Iterator iterator = segResults.iterator();
                String buf = "";
                while (iterator.hasNext()) {
                    String term = (String) iterator.next();
                    if (term.trim().equals(""))
                        continue;
                    String SQL = "";
                    String[] terms = term.split("/");
                    String word = "";
                    word = terms[0];
                    buf += word + " ";
                }
                return buf;

        } catch (Exception e) {
            logger.error("分词异常");
            e.printStackTrace();
        }

        return "";
    }


    private static boolean isEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
                || (codePoint == 0xD)
                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
                || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }

    /**
     * 过滤emoji 或者 其他非文字类型的字符
     *
     * @param source
     * @return
     */
    public static String filterEmoji(String source) {
        if (StringUtils.isBlank(source)) {
            return source;
        }
        StringBuilder buf = null;
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (isEmojiCharacter(codePoint)) {
                if (buf == null) {
                    buf = new StringBuilder(source.length());
                }
                buf.append(codePoint);
            }
        }
        if (buf == null) {
            return source;
        } else {
            if (buf.length() == len) {
                buf = null;
                return source;
            } else {
                return buf.toString();
            }
        }
    }
}


